//
//  ZCNetworkManager.h
//  YZYSDKManagerDemo
//
//  Created by 赵隆杰 on 2024/6/7.
//

#import "ZCNetworkManager.h"
#import <CommonCrypto/CommonCryptor.h>
#import <Security/Security.h>

#import "YZYSaccountStore.h"
#import "ZCFunDataFormat.h"
#import "YZYUUID.h"
#import "MBProgressHUD.h"
#import "YZYSDKManagerHeader.h"
#import "YZYSDKManager.h"
#import "GTMBase64.h"


#define gkey            @"c5fcdac4fc05bb8bbe244862cb8e0b05"
#define gIv             @"20220409"

NSString *const ZCSResponseErrorKey = @"com.alamofire.serialization.response.error.response";
NSInteger const ZCSInterval = 10;

@interface ZCNetworkManager()

@end

@implementation ZCNetworkManager
//原生GET网络请求
+ (void)getWithURL:(NSString *)url Params:(NSDictionary *)params success:(SuccessBlock)success failure:(FailureBlock)failure {
    [self getWithURL:url Params:params isOpenLoading:NO success:success failure:failure];
}
+ (void)getWithURL:(NSString *)url Params:(NSDictionary *)params isOpenLoading:(BOOL)isOpenLoading success:(SuccessBlock)success failure:(FailureBlock)failure {
    //完整URL
    NSString *urlString = [NSString string];
    if (params) {
        //参数拼接url
        NSString *paramStr = [self dealWithParam:params];
        urlString = [NSString stringWithFormat:@"%@?%@",url,paramStr];
    }else{
        urlString = url;
    }
    //对URL中的中文进行转码
    NSString *pathStr = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:pathStr]];
    
    NSString* accessToken = [[YZYSaccountStore sharedInstance] getAccessToken];
    NSString *packageName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    NSString *app_Version = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    
    if (![ZCFunDataFormat isBlankString:accessToken]) {
        [request setValue:accessToken forHTTPHeaderField:@"accessToken"];
    }
    [request setValue:@"ios" forHTTPHeaderField:@"osType"];
    [request setValue:packageName forHTTPHeaderField:@"package_name"];
    [request setValue:app_Version forHTTPHeaderField:@"app_version"];
    [request setValue:[ZCFunDataFormat GetChanneNo] forHTTPHeaderField:@"channel_no"];
    [request setValue:[YZYUUID uuidForIDFV] forHTTPHeaderField:@"idfv"];
    [request setValue:[YZYUUID uuidForIDFA] forHTTPHeaderField:@"idfa"];
    [request setValue:[YZYUUID uuidForKeychain] forHTTPHeaderField:@"uuid"];
    [request setValue:[ZCFunDataFormat GetQPGameID] forHTTPHeaderField:@"qp_gameid"];
    [request setValue:[ZCFunDataFormat GetPlatformGameID] forHTTPHeaderField:@"ml_gameid"];
    
    request.timeoutInterval = ZCSInterval;
    if (isOpenLoading) {
        [[YZYSaccountStore sharedInstance] showHUDAddedToWindow];
    }
    NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        [[YZYSaccountStore sharedInstance] hideHUDForWindow];
        if (data) {
            NSDictionary *surperdic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            NSLog(@"yzysdk - -----------GET urlString- %@, headers- %@, params- %@, success- %@", urlString, request.allHTTPHeaderFields, params, surperdic);
            NSString *surpercode = [NSString stringWithFormat:@"%@",surperdic[@"code"]];
            NSString *msg = [NSString stringWithFormat:@"%@",surperdic[@"msg"]];
            if ([surpercode isEqualToString:@"200"]) {
                success(surperdic);
            } else {
                if ([surpercode isEqualToString:YZY_Alert_Notice]) {
                    //弹窗提示维护
                    [[YZYSaccountStore sharedInstance] makeAlertViewFromWindow:msg];
                } else 
                if (![[YZYSDKManager shareManager] isLogin] && [surpercode isEqualToString:@"500"] && [msg isEqualToString:@"请登录"]) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[YZYSaccountStore sharedInstance] reLogin];
                    });
                } else {
                    if ([url hasSuffix:YZY_getIosVersion] || [url hasSuffix:YZY_pay_notify]) {
                    } else {
                        [[YZYSaccountStore sharedInstance] makeToastFromWindow:msg];
                    }
                }
                failure(surpercode);
            }
            
        }else{
            NSHTTPURLResponse *httpResponse = error.userInfo[ZCSResponseErrorKey];
            
            if (httpResponse.statusCode != 0) {
                
                NSString *ResponseStr = [self showErrorInfoWithStatusCode:httpResponse.statusCode];
                NSLog(@"yzysdk - -----------GET urlString- %@, error- %@", urlString, ResponseStr);
                failure(ResponseStr);
                
            } else {
                NSString *ErrorCode = [self showErrorInfoWithStatusCode:error.code];
                NSLog(@"yzysdk - -----------GET urlString- %@, error- %@", urlString, ErrorCode);
                failure(ErrorCode);
            }
        }
    }];
    
    [task resume];
}

//原生POST请求
+ (void)postWithURL:(NSString *)url Params:(NSDictionary *)params success:(SuccessBlock)success failure:(FailureBlock)failure {
    [self postWithURL:url Params:params isOpenLoading:NO success:success failure:failure];
}
+ (void)postWithURL:(NSString *)url Params:(NSDictionary *)params isOpenLoading:(BOOL)isOpenLoading success:(SuccessBlock)success failure:(FailureBlock)failure {
    NSDictionary *body = [NSDictionary dictionary];
    if (params) {
        body = [params copy];
    }
    
    NSError *error;
    NSData *bodyData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];
    if (error) {
        NSString *errorStr = [NSString stringWithFormat:@"Error serializing JSON: %@", error];
        [[YZYSaccountStore sharedInstance] makeToastFromWindow:errorStr];
        failure(errorStr);
        return;
    }
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    [request setHTTPMethod:@"POST"];
    //设置请求体
    [request setHTTPBody:bodyData];
    
    NSString* accessToken = [[YZYSaccountStore sharedInstance] getAccessToken];
    NSString *packageName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    NSString *app_Version = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    
    if (![ZCFunDataFormat isBlankString:accessToken]) {
        [request setValue:accessToken forHTTPHeaderField:@"accessToken"];
    }
    [request setValue:@"ios" forHTTPHeaderField:@"osType"];
    [request setValue:packageName forHTTPHeaderField:@"package_name"];
    [request setValue:app_Version forHTTPHeaderField:@"app_version"];
    [request setValue:[ZCFunDataFormat GetChanneNo] forHTTPHeaderField:@"channel_no"];
    [request setValue:[YZYUUID uuidForIDFV] forHTTPHeaderField:@"idfv"];
    [request setValue:[YZYUUID uuidForIDFA] forHTTPHeaderField:@"idfa"];
    [request setValue:[YZYUUID uuidForKeychain] forHTTPHeaderField:@"uuid"];
    [request setValue:[ZCFunDataFormat GetQPGameID] forHTTPHeaderField:@"qp_gameid"];
    [request setValue:[ZCFunDataFormat GetPlatformGameID] forHTTPHeaderField:@"ml_gameid"];
    
    //设置本次请求的数据请求格式
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    // 设置本次请求请求体的长度(因为服务器会根据你这个设定的长度去解析你的请求体中的参数内容)
    [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)bodyData.length] forHTTPHeaderField:@"Content-Length"];
    //设置请求最长时间
    request.timeoutInterval = ZCSInterval;
    if (isOpenLoading) {
        [[YZYSaccountStore sharedInstance] showHUDAddedToWindow];
    }
    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        [[YZYSaccountStore sharedInstance] hideHUDForWindow];
        if (data) {
            //利用iOS自带原生JSON解析data数据 保存为Dictionary
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            NSLog(@"yzysdk - -----------POST url- %@, headers- %@, params- %@, success- %@", url, request.allHTTPHeaderFields, params, dict);
            NSString *surpercode = [NSString stringWithFormat:@"%@",dict[@"code"]];
            NSString *msg = [NSString stringWithFormat:@"%@",dict[@"msg"]];
            if ([surpercode isEqualToString:@"200"]) {
                success(dict);
            } else {
                if ([surpercode isEqualToString:YZY_Alert_Notice]) {
                    //弹窗提示维护
                    [[YZYSaccountStore sharedInstance] makeAlertViewFromWindow:msg];
                } else 
                if (![[YZYSDKManager shareManager] isLogin] && [surpercode isEqualToString:@"500"] && [msg isEqualToString:@"请登录"]) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[YZYSaccountStore sharedInstance] reLogin];
                    });
                } else {
                    if ([url hasSuffix:YZY_getIosVersion] || [url hasSuffix:YZY_pay_notify]) {
                    } else {
                        [[YZYSaccountStore sharedInstance] makeToastFromWindow:msg];
                    }
                }
                failure(surpercode);
            }
            
        }else{
            NSHTTPURLResponse *httpResponse = error.userInfo[ZCSResponseErrorKey];
            if (httpResponse.statusCode != 0) {
                
                NSString *ResponseStr = [self showErrorInfoWithStatusCode:httpResponse.statusCode];
                NSLog(@"yzysdk - -----------POST url- %@, headers- %@, params- %@, success- %@", url, request.allHTTPHeaderFields, params, ResponseStr);
                failure(ResponseStr);
            } else {
                NSString *ErrorCode = [self showErrorInfoWithStatusCode:error.code];
                NSLog(@"yzysdk - -----------POST url- %@, headers- %@, params- %@, success- %@", url, request.allHTTPHeaderFields, params, ErrorCode);
                failure(ErrorCode);
            }
        }
    }];
    [task resume];
}

//加密
+ (NSString *)doEncryptStr:(NSString *)originalStr{
    
    NSData* data = [originalStr dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t plainTextBufferSize = [data length];
    
    const void *vplainText = (const void *)[data bytes];
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
    const void *vkey = (const void *) [gkey UTF8String];
 
    const void *vinitVec = (const void *) [gIv UTF8String];
    
    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey,
                       kCCKeySize3DES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    NSString *result = [GTMBase64 stringByEncodingData:myData];
    return result;
}


#pragma mark -- 拼接参数
+ (NSString *)dealWithParam:(NSDictionary *)param
{
    NSArray *allkeys = [param allKeys];
    NSMutableString *result = [NSMutableString string];
    
    for (NSString *key in allkeys) {
        NSString *string = [NSString stringWithFormat:@"%@=%@&", key, param[key]];
        [result appendString:string];
    }
    NSString *str = [NSString stringWithFormat:@"%@",[result substringWithRange:NSMakeRange(0, [result length] - 1)]];

    return str;
}

#pragma mark
+ (NSString *)showErrorInfoWithStatusCode:(NSInteger)statusCode{
    
    NSString *message = nil;
    switch (statusCode) {
        case 401: {
            
        }
            break;
            
        case 500: {
            message = @"服务器异常！";
        }
            break;
            
        case -1001: {
            message = @"网络请求超时，请稍后重试！";
        }
            break;
            
        case -1002: {
            message = @"不支持的URL！";
        }
            break;
            
        case -1003: {
            message = @"未能找到指定的服务器！";
        }
            break;
            
        case -1004: {
            message = @"服务器连接失败！";
        }
            break;
            
        case -1005: {
            message = @"连接丢失，请稍后重试！";
        }
            break;
            
        case -1009: {
            message = @"互联网连接似乎是离线！";
        }
            break;
            
        case -1012: {
            message = @"操作无法完成！";
        }
            break;
            
        default: {
            message = @"网络请求发生未知错误，请稍后再试！";
        }
            break;
    }
    return message;
    
}

@end
